/** **********************************************************************************
 * @file    2.A.c
 * @mainpage
 * @date    2013-09-29 22:33
 * @author  Alexey Kulikov <alexeyqu@gmail.com>, group 376, DCAM MIPT
 * @version 1.00
 *
 * Transpose the matrix from the input
 *
 * @par     The task.
 *          The program gets size of matrix and its elements.
 *          It prints transposed matrix from the input.
 *
 * @note    The matrix is realised by one-dimensional dynamic array.
 *
 * @warning Consider that size of matrix cannot be 50 or more.
 *          Absolute values of the elements are less than 2^31.
**************************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

#define DEBUG

#ifdef DEBUG
    #define DBG printf ("# "),
    #define ASSERT(cond)                                                              \
    if (!(cond))                                                                      \
    {                                                                                 \
        printf ("Critical failure in assertion '%s'! \nfile %s, line %d \n"           \
                "Now keep calm and EXTERMINATE! EXTERMINATE! EXTERMINATE!!!\n"        \
                , #cond, __FILE__, __LINE__);                                         \
        abort();                                                                      \
    }
#else
    #define DBG if (0)
    #define ASSERT(cond)
#endif

/** ********************************************************************************
 * Fill_Matrix - fills the empty matrix by values from the input stream
 *
 * @param   Matrix      matrix to fill
 *          dimension   heigth\width of the matrix
 *          length      quantity of elements (equal to dimension^2)
************************************************************************************/
void Fill_Matrix (long long int* Matrix, int dimension, int length);

int main()
{
    DBG printf ("C language test'07. \n");
    DBG printf ("2.A problem. \n");
    DBG printf ("Transposition of N-N matrix. \n");
    DBG printf ("Enter N: \n-> ");

    int res_input = 0; //!< value that controls correct input
    int dimension = 0; //!< Size of matrix

    res_input = scanf ("%d", &dimension);
    ASSERT (res_input); ASSERT (dimension > 0); ASSERT (dimension < 50);

    int length = dimension*dimension;
    long long int* Matrix = NULL;

    Matrix = (long long int*) calloc (length, sizeof (long long int));
    ASSERT (Matrix);

    DBG printf ("Enter %d elements of matrix to transpose: \n->", length);

    Fill_Matrix (Matrix, dimension, length);

    DBG printf ("Result of transposition: \n");

    int i = 0, j = 0; //!< Counters

    for (i = 0; i < dimension; i++)
    {
        for (j = 0; j < dimension; j++)
        {
            ASSERT (i*dimension + j < length);
            printf ("%lld ", Matrix[j*dimension + i]);
        }

        printf ("\n");
    }

    free (Matrix);

    return 0;
}

void Fill_Matrix (long long int* Matrix, int dimension, int length)
{
    int i = 0, j = 0; //!< Counters
    int res_input = 0; //!< value that controls correct input
    long long int x = 0; //!< Each element in input

    for (i = 0; i < dimension; i++)
    {
        for (j = 0; j < dimension; j++)
        {
            res_input = scanf ("%lld", &x);
            ASSERT (res_input); ASSERT (abs (x) < LONG_MAX);

            ASSERT (i*dimension + j < length);
            Matrix[i*dimension + j] = x;
        }
    }
}
